# define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define EASY_ROWS 9
#define EASY_COLS 9
#define EASY_MINES 10

#define MEDIUM_ROWS 16
#define MEDIUM_COLS 16
#define MEDIUM_MINES 40

#define HARD_ROWS 16
#define HARD_COLS 30
#define HARD_MINES 99

char board[EASY_ROWS][EASY_COLS];
char mineBoard[EASY_ROWS][EASY_COLS];
int revealed[EASY_ROWS][EASY_COLS];

int rows, cols, mines;

void initializeBoard() {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            board[i][j] = '-';
            mineBoard[i][j] = 0;
            revealed[i][j] = 0;
        }
    }
}

void printBoard() {
    printf("   ");
    for (int i = 0; i < cols; i++) {
        printf("%d ", i);
    }
    printf("\n");
    for (int i = 0; i < rows; i++) {
        printf("%d |", i);
        for (int j = 0; j < cols; j++) {
            if (revealed[i][j]) {
                printf("%c ", board[i][j]);
            }
            else {
                printf("- ");
            }
        }
        printf("\n");
    }
}

void placeMines() {
    srand(time(0));
    int count = 0;
    while (count < mines) {
        int row = rand() % rows;
        int col = rand() % cols;
        if (mineBoard[row][col] != '*') {
            mineBoard[row][col] = '*';
            count++;
        }
    }
}

int countAdjacentMines(int row, int col) {
    int count = 0;
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            int newRow = row + i;
            int newCol = col + j;
            if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols) {
                if (mineBoard[newRow][newCol] == '*') {
                    count++;
                }
            }
        }
    }
    return count;
}

void reveal(int row, int col) {
    if (revealed[row][col]) {
        return;
    }
    revealed[row][col] = 1;
    if (mineBoard[row][col] == '*') {
        printf("Game Over! You stepped on a mine.\n");
        exit(0);
    }
    int adjMines = countAdjacentMines(row, col);
    if (adjMines > 0) {
        board[row][col] = adjMines + '0';
    }
    else {
        board[row][col] = ' ';
        for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
                int newRow = row + i;
                int newCol = col + j;
                if (newRow >= 0 && newRow < rows && newCol >= 0 && newCol < cols) {
                    reveal(newRow, newCol);
                }
            }
        }
    }
}

int main() {
    int difficulty;
    printf("Choose difficulty level:\n");
    printf("1. Easy\n2. Medium\n3. Hard\n");
    scanf("%d", &difficulty);

    switch (difficulty) {
    case 1:
        rows = EASY_ROWS;
        cols = EASY_COLS;
        mines = EASY_MINES;
        break;
    case 2:
        rows = MEDIUM_ROWS;
        cols = MEDIUM_COLS;
        mines = MEDIUM_MINES;
        break;
    case 3:
        rows = HARD_ROWS;
        cols = HARD_COLS;
        mines = HARD_MINES;
        break;
    default:
        printf("Invalid difficulty level. Choosing easy by default.\n");
        rows = EASY_ROWS;
        cols = EASY_COLS;
        mines = EASY_MINES;
        break;
    }

    initializeBoard();
    placeMines();

    int row, col;
    int remainingCells = rows * cols - mines;
    time_t startTime, currentTime;
    time(&startTime);

    while (1) {
        printBoard();
        printf("Enter row and column to reveal or flag (format: 'row col f' for flag): ");
        scanf("%d %d", &row, &col);
        char action;
        scanf(" %c", &action);

        if (row < 0 || row >= rows || col < 0 || col >= cols) {
            printf("Invalid input. Please try again.\n");
            continue;
        }

        if (action == 'f') {
            // Flag or unflag the cell
            if (board[row][col] == 'F') {
                board[row][col] = '-';
            }
            else {
                board[row][col] = 'F';
            }
        }
        else {
            if (revealed[row][col]) {
                printf("Cell already revealed. Please try again.\n");
                continue;
            }
            if (mineBoard[row][col] == '*') {
                printf("Game Over! You stepped on a mine.\n");
                exit(0);
            }
            reveal(row, col);
            remainingCells--;
            if (remainingCells == 0) {
                printf("Congratulations! You cleared the minefield!\n");
                time(&currentTime);
                int timeTaken = difftime(currentTime, startTime);
                printf("Time taken: %d seconds\n", timeTaken);
                exit(0);
            }
        }
    }
    return 0;
}

